﻿using System;
using System.Globalization;
using System.Net;
using System.Reflection;
using System.Text;
using LIK.NetworkTools;

namespace LIK.WakeOnLan.Network
{
    [Serializable]
    public class NetworkClient
    {
        [Obfuscation(Exclude = true)]
        public int StatusId
        {
            get { return (int)this.Status; }
        }

        [NonSerialized]
        public NetworkClientStatus Status;

        [Obfuscation(Exclude = true)]
        public NetworkClientFavoritesStatus FavStatus { get; set; }


        public IPAddress BroadCastIpAddress
        {
            get
            {
                string strIpAddress = this.IpAddress;

                if (string.IsNullOrEmpty(this.IpAddress))
                {
                    var ipAddress = IpHelper.GetLocalIpAddress();
                    if (ipAddress != null)
                    {
                        strIpAddress = ipAddress.ToString();
                    }
                    if (string.IsNullOrEmpty(strIpAddress))
                    {
                        strIpAddress = "255.255.255.255";
                    }
                }
                var ipData = strIpAddress.Split('.');
                ipData[ipData.Length - 1] = "255";
                strIpAddress = string.Concat(ipData[0], ".", ipData[1], ".", ipData[2], ".", ipData[3]);
                return IPAddress.Parse(strIpAddress);
            }
        }

        public byte[] MacAddresInBytes
        {
            get
            {
                var bytes = new byte[6];
                var macAddressData = MacAddress.Split(':');
                for (int i = 0; i < 6; i++)
                {
                    bytes[i] = byte.Parse(macAddressData[i], NumberStyles.HexNumber);
                }
                return bytes;
            }
        }

        [Obfuscation(Exclude = true)]
        public string MacAddress { get; set; }

        public int Port { get; set; }

        [Obfuscation(Exclude = true)]
        public string HostName { get; set; }

        [Obfuscation(Exclude = true)]
        public string IpAddress { get; set; }

        public string IpMask { get; set; }

        public NetworkClient()
            : this("", "", "")
        {
        }

        public NetworkClient(string title, string ipAddress, string macAddress)
        {
            this.HostName = title;
            this.IpAddress = ipAddress;
            this.IpMask = "255.255.255.0";
            this.MacAddress = macAddress;
            this.Port = 12287;
            this.Status = NetworkClientStatus.UnkNown;
            this.FavStatus = NetworkClientFavoritesStatus.None;
        }

        internal void Update(string title, string ip, string mac, int port)
        {
            this.HostName = title;
            this.IpAddress = ip;
            this.MacAddress = mac;
            this.Port = port;
        }

        public IPAddress GetIpAddress()
        {
            return IPAddress.Parse(this.IpAddress);
        }

        public bool IsUnresolvedHostName()
        {
            return (string.IsNullOrEmpty(this.HostName) || this.HostName.Equals("?"));
        }

        public bool IsOnline()
        {
            return IpHelper.IsHostAccessible(this.IpAddress);
        }

        public override string ToString()
        {
            return string.Format("{0} [{1}]", this.HostName, this.MacAddress);
        }

        public string GetFullInfo()
        {
            var sb = new StringBuilder();
            sb.Append("IP: ");
            sb.Append(this.IpAddress);
            sb.Append(Environment.NewLine);
            sb.Append("Mask: ");
            sb.Append(this.IpMask);
            sb.Append(Environment.NewLine);
            sb.Append("Port: ");
            sb.Append(this.Port);
            return sb.ToString();
        }

    }
}
